/*
 * Copyright 2010 Christoph Widulle (christoph.widulle@googlemail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */



package org.amarena2d.examples.scenes.invader;

import com.android1.amarena2d.actions.base.Action;
import com.android1.amarena2d.actions.base.RepeatForever;
import com.android1.amarena2d.actions.base.RunAction;
import com.android1.amarena2d.actions.base.Sequence;
import com.android1.amarena2d.actions.ease.EaseOut;
import com.android1.amarena2d.actions.movement.MoveBy;
import com.android1.amarena2d.commons.collections.ReadOnlyCollectionAccess;
import com.android1.amarena2d.commons.event.Event;
import com.android1.amarena2d.engine.collision.Collision;
import com.android1.amarena2d.engine.collision.CollisionCallback;
import com.android1.amarena2d.nodes.behavior.delegates.CollisionDelegate;
import com.android1.amarena2d.nodes.sprites.BatchedSprite;
import com.android1.amarena2d.nodes.sprites.SpriteBatchNode;
import com.android1.amarena2d.texture.Textures;
import com.badlogic.gdx.audio.Sound;

public class InvaderBatch extends SpriteBatchNode<InvaderBatch.Invader> {

    private int activeInvader;
    private final int invaderX = 8;
    private final int invaderY = 3;

    float posx = 240 - ((invaderX * 40) / 2);
    float posy = 280;

    private final Action move =
            RepeatForever.$(
                    Sequence.$(
                            MoveBy.$(40, 0, 1),
                            MoveBy.$(-80, 0, 2),
                            MoveBy.$(40, 0, 1)));

    //The Invader will move down from the top to the start position. They will make their normal left to right movement when this has been done.
    private final Action intro = Sequence.$(EaseOut.$(3, MoveBy.$(0, -120, 1)), RunAction.$(move));

    public InvaderBatch() {

        super(Textures.$("invader/invader.png").get());

        ensureChildren(invaderX * invaderY);

        for (int i = 0; i < invaderX; i++) {
            float x = i * 40 + posx;
            for (int i2 = 0; i2 < invaderY; i2++) {
                float y = posy - i2 * 40;
                Invader invader = new Invader(x, y);
                add(invader);

            }
        }

        setVisible(false);
    }


    public void start() {

        setXY(0, 120);

        action().run(intro);

        activeInvader = invaderX * invaderY;

        Invader invader;
        final ReadOnlyCollectionAccess<Invader> children = this.getChildren();
        children.itr();
        while ((invader = children.next()) != null) {
            invader.start();
        }
        //time to show the phantom menace
        setVisible(true);
    }

    public void stop(){
        action().stopAll();
    }

    public void reduceInvader() {
        activeInvader--;
        if (activeInvader == 0) {
            engine.getEventBus().fire(Events.GAME_FINISHED);
        }
    }


    public final class Invader extends BatchedSprite {

        Sound explosion;

        public Invader(float x, float y) {
            super(x, y);
        }


        @Override
        protected void onInit() {
            explosion = engine.getAudioManager().getSound("invader/explosion.ogg");

            collision().setCheckBehaviour(Collision.CheckBehaviour.Passive)
                    .setVolumeBox(3, 5, 26, 22)
                    .setOnCollision(new CollisionCallback() {
                        @Override
                        public void on(CollisionDelegate self,CollisionDelegate target) {
                            destroy();
                        }
                    });
        }

        public void start() {
            collision().register();
            setActive(true);
        }

        public void destroy() {
            engine.getEventBus().fire(Event.obtain(Events.INVADER_DESTROYED, this.getAbsoluteX() + 16, this.getAbsoluteY() + 16));
            explosion.play();
            reduceInvader();
            collision().unregister();
            setActive(false);

        }


    }

}
